package com.techysky.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaBuilder.In;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import com.techysky.entity.DataModule;
import com.techysky.entity.PmDm;
import com.techysky.entity.PublicModule;
import com.techysky.repository.DataModuleRepository;
import com.techysky.repository.PmDmRepository;
import com.techysky.service.DataModuleService;
import com.techysky.util.CoreUtils;

/**
 * @author nichao
 * @date 2017-7-18
 * @remark 业务实现类
 */
@Service("dataModuleService")
public class DataModuleServiceImpl implements DataModuleService {

	private static final String CONTENT = "content";
	private static final long serialVersionUID = 1L;
	@Autowired
	private PmDmRepository pmDmRepository;
	@Autowired
	private DataModuleRepository dataModuleRepository;
	
	/**
	 * 查询
	 * @param dictionary
	 * @return
	 */
	@Override
	public List<DataModule> findByPublicModuleId(String id) {
		return this.dataModuleRepository.findByPublicModuleId(id);
	}
	/**
	 * 查询结果集
	 * @param dataModule
	 * @return
	 */
	@Override
	public List<DataModule> query(DataModule dataModule) {
		return this.dataModuleRepository.findAll(queryConditions(dataModule));
	}

	/**
	 * 等值匹配条件
	 * @return
	 */
	public Specification<DataModule> queryConditions(final DataModule dataModule){
		return (Root<DataModule> root,CriteriaQuery<?> query, CriteriaBuilder cb)->{
            List<Predicate> predicate = new ArrayList<>();
            if(dataModule.getDmTitle()!=null&&!"".equals(dataModule.getDmTitle()))
            	predicate.add(cb.like(root.get("dmTitle"), "%"+dataModule.getDmTitle()+"%"));
            else if(dataModule.getContent()!=null&&!"".equals(dataModule.getContent()))
            	predicate.add(cb.like(root.get(CONTENT), "%"+dataModule.getContent()+"%"));
            predicate.add(cb.isNotNull(root.get("content")));
            extract2(dataModule, root, cb, predicate);
            Predicate[] pre = new Predicate[predicate.size()];
            return query.where(predicate.toArray(pre)).getRestriction();
		};
	}
	private void extract2(final DataModule dataModule, Root<DataModule> root, CriteriaBuilder cb,
			List<Predicate> predicate) {
		if(dataModule.getPmCode()!=null&&!"".equals(dataModule.getPmCode())&&!"1".equals(dataModule.getPmCode())){
        	predicate.add(cb.equal(root.get("pmCode"), dataModule.getPmCode()));
        }
		if(dataModule.getModelIdentCode()!=null&&!"".equals(dataModule.getModelIdentCode())&&!"1".equals(dataModule.getModelIdentCode())){
			predicate.add(cb.equal(root.get("modelIdentCode"), dataModule.getModelIdentCode()));
		}
		if(dataModule.getSystemCode()!=null&&!"".equals(dataModule.getSystemCode())&&!"1".equals(dataModule.getSystemCode())){
			predicate.add(cb.equal(root.get("systemCode"), dataModule.getSystemCode()));
		}
		extract4(dataModule, root, cb, predicate);
	}
	private void extract4(final DataModule dataModule, Root<DataModule> root, CriteriaBuilder cb,
			List<Predicate> predicate) {
		if(dataModule.getSubSystemCode()!=null&&!"".equals(dataModule.getSubSystemCode())&&!"1".equals(dataModule.getSubSystemCode())){
			predicate.add(cb.equal(root.get("subSystemCode"), dataModule.getSubSystemCode().substring(0, 1)));
			predicate.add(cb.equal(root.get("subSubSystemCode"), dataModule.getSubSystemCode().substring(1, dataModule.getSystemCode().length())));
		}
		extract5(dataModule, root, cb, predicate);
		if(dataModule.getSearchWords()!=null&&!"".equals(dataModule.getSearchWords())){
		extract3(dataModule, root, cb, predicate);
		}
	}
	private void extract5(final DataModule dataModule, Root<DataModule> root, CriteriaBuilder cb,
			List<Predicate> predicate) {
		if(dataModule.getAssyCode()!=null&&!"".equals(dataModule.getAssyCode())&&!"1".equals(dataModule.getAssyCode())){
			predicate.add(cb.equal(root.get("assyCode"), dataModule.getAssyCode()));
		}
		if(dataModule.getInfoCode()!=null&&!"".equals(dataModule.getInfoCode())&&!"1".equals(dataModule.getInfoCode())){
			predicate.add(cb.equal(root.get("infoCode"), dataModule.getInfoCode()));
		}
	}
	private void extract3(final DataModule dataModule, Root<DataModule> root, CriteriaBuilder cb,
			List<Predicate> predicate) {
		if(dataModule.getSearchType()!=null&&"1".equals(dataModule.getSearchType())){
			String[] searchArray=dataModule.getSearchWords().split(",");
			for(int i=0;i<searchArray.length;i++){
				predicate.add(cb.like(root.get(CONTENT), "%"+searchArray[i]+"%"));
			}
		}
		else if(dataModule.getSearchType()!=null&&"2".equals(dataModule.getSearchType())){
			String[] searchArray=dataModule.getSearchWords().split(",");
			Predicate[] pre2 = new Predicate[searchArray.length];
			for(int i=0;i<searchArray.length;i++){
				Predicate p=cb.like(root.get(CONTENT), "%"+searchArray[i]+"%");
				pre2[i]=p;
			}
			predicate.add(cb.or(pre2));
		}
		else {
			extract6(dataModule, root, cb, predicate);
			}
	}
	private void extract6(final DataModule dataModule, Root<DataModule> root, CriteriaBuilder cb,
			List<Predicate> predicate) {
		if(dataModule.getSearchType()!=null&&"3".equals(dataModule.getSearchType())){
			predicate.add(cb.like(root.get(CONTENT), "%"+dataModule.getSearchWords()+"%"));
			}
		else if(dataModule.getSearchType()!=null&&"4".equals(dataModule.getSearchType())){
		String[] searchArray=dataModule.getSearchWords().split(",");
		for(int i=0;i<searchArray.length;i++){
			predicate.add(cb.notLike(root.get(CONTENT), "%"+searchArray[i]+"%"));
		}
		}
	}
	/**
	 * 查询结果集-用于考试系统通过pm获取所有dm
	 * @param dataModule
	 * @return
	 */
	@Override
	public Map<String, Object> queryAllDm(List<PublicModule> pmList,String title,int page,int size) {
		Map<String,Object> result=new HashMap<>();
		Page<DataModule> resultList=this.dataModuleRepository.findAll(queryConditionsAllDm(pmList,title),new PageRequest(page,size));
		List<Map<String,Object>> results=CoreUtils.getInstance().convert(resultList.getContent());
		result.put("rows", results);
		return result;
	}
	/**
	 * 等值匹配条件
	 * @return
	 */
	public Specification<DataModule> queryConditionsAllDm(List<PublicModule> pmList,String title){
		return (Root<DataModule> root,CriteriaQuery<?> query, CriteriaBuilder cb)->{
            List<Predicate> predicate = new ArrayList<>();
            if(null!=title&&!"".equals(title))
            	predicate.add(cb.like(root.get("dmTitle"), "%"+title+"%"));
            if(!pmList.isEmpty()){
            	In<String> inIds = cb.in(root.get("publicModuleId"));
            	for (PublicModule pm : pmList) {
            		inIds.value(pm.getId());
				}
            	predicate.add(inIds);
            }
            predicate.add(cb.isNotNull(root.get("content")));
            Predicate[] pre = new Predicate[predicate.size()];
            return query.where(predicate.toArray(pre)).getRestriction();
		};
	}
	/**
	 * 
	 */
	@Override
	public DataModule saveOrUpdate(DataModule dataModule) {
		return this.dataModuleRepository.saveAndFlush(dataModule);
	}


	
	@Override
	public List<DataModule> findByProjectId(String projectId) {
		return this.dataModuleRepository.findByProjectId(projectId);
	}
	
	@Override
	public List<DataModule> findByDmCodeAndPublicModuleIdIsNotNull(String dmCode){
		return this.dataModuleRepository.findByDmCodeAndPublicModuleIdIsNotNull(dmCode);
	}

	@Override
	public List<Map<String,Object>> getModelIdentCodeList(String pmcode) {
		return this.dataModuleRepository.getModelIdentCodeList(pmcode);
	}
	@Override
	public List<Map<String,Object>> getSystemCodeList(String pmcode, String dmcode) {
		return this.dataModuleRepository.getSystemCodeList(pmcode,  dmcode);
	}
	@Override
	public List<Map<String,Object>> getSubSystemCodeList(String pmcode, String dmcode, String systemCode) {
		return this.dataModuleRepository.getSubSystemCodeList( pmcode,  dmcode,  systemCode);
	}
	@Override
	public List<Map<String,Object>> getAssyCodeList(String pmcode, String dmcode, String systemCode, String subSystemCode) {
		return this.dataModuleRepository.getAssyCodeList( pmcode,  dmcode,  systemCode,  subSystemCode);
	}
	@Override
	public List<Map<String,Object>> getInfoCodeList(String pmcode, String dmcode, String systemCode, String subSystemCode, String assyCode) {
		return this.dataModuleRepository.getInfoCodeList( pmcode,  dmcode,  systemCode,  subSystemCode,  assyCode);
	}
	@Override
	public void saveOrUpdate(String projectId, String fitName) {
		
		List<DataModule> fitList = this.dataModuleRepository.findByProjectId(projectId);
		for(int i=0;i<fitList.size();i++){
			DataModule dm = fitList.get(i);
			dm.setState("1");
			this.dataModuleRepository.save(dm);		
		}
	}
	@Override
	public DataModule getObject(String id) {
		return this.dataModuleRepository.findOne(id);
	}
	@Override
	public DataModule getDMByIndex(Integer index) {
		PmDm pd=this.pmDmRepository.findByOrderCode(index);
		if(!ObjectUtils.isEmpty(pd)) {
			return dataModuleRepository.findOne(pd.getDmId());
		}
		return new DataModule();
	}
	@Override
	public DataModule findByDmCode(String dmCode) {
		return this.dataModuleRepository.findByDmCode(dmCode);
	}
}
